package com.tul.exercise.base.java8.stream;

import com.tul.exercise.base.java8.stream.base.Album;
import com.tul.exercise.base.java8.stream.base.Apple;
import com.tul.exercise.base.java8.stream.base.Track;
import jdk.internal.org.objectweb.asm.util.TraceAnnotationVisitor;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * Stream基本操作
 *
 * @author tuliang
 */
public class StreamTest {
    @Test
    @DisplayName("max和min操作")
    public void test01() {
        List<Apple> appleList = createAppleList(5);

        // 选出最重的苹果
        Optional<Apple> apple = appleList.stream()
                .max(Comparator.comparing(Apple::getWeight));
        System.out.println(apple.get());

        // min同理

    }

    @Test
    @DisplayName("limit和skip操作")
    public void test02() {
        List<Apple> appleList = createAppleList(5);

        appleList.stream().skip(3).forEach(System.out::println);

        System.out.println("\n");
        appleList.stream().limit(2).forEach(System.out::println);
    }

    @Test
    @DisplayName("flatMap操作")
    public void test03() {
        List<Album> albums = createAlbumList(20);

        albums.stream().flatMap(album -> album.getTrackList().stream())
                .forEach(System.out::println);

        System.out.println("\n");
    }

    @Test
    @DisplayName("distinct和count操作")
    public void test04() {
        List<Album> albums = createAlbumList(20);

        String trackNames = albums.stream().flatMap(album -> album.getTrackList().stream())
                .map(track -> track.getName())
                .distinct()
                .collect(Collectors.joining(","));
        System.out.println(trackNames);

        long count = albums.stream().flatMap(album -> album.getTrackList().stream())
                .map(track -> track.getName())
                .distinct()
                .count();
        System.out.println(count);

    }

    @Test
    @DisplayName("anyMatch和noneMatch操作")
    public void test05() {
        List<Album> albums = createAlbumList(20);

        Predicate<Track> isTrackName = track -> track.getName().equals("高山流水");
        boolean result = albums.stream().flatMap(album -> album.getTrackList().stream())
                .anyMatch(isTrackName);
        System.out.println("track name is '高山流水':" + result);

        boolean result2 = albums.stream().noneMatch(album -> album.getMusicians().size() == 8);


    }

    @Test
    @DisplayName("findMatch和noneMatch操作")
    public void test06() {
        List<Album> albums = createAlbumList(20);


        Predicate<Track> isTrackName = track -> track.getName().equals("高山流水");
        Track track = albums.stream().flatMap(album -> album.getTrackList().stream())
                .findAny()
                .orElse(new Track("",0.0));
        System.out.println(track);


    }

    @Test
    @DisplayName("reduce:操作")
    public void test07() {


    }

    /**
     * 获取Apple List
     *
     * @param num 个数
     * @return List<Apple>
     */
    public List<Apple> createAppleList(int num) {
        return Apple.createApples(num);
    }

    /**
     * 获取AAlbum List
     *
     * @param num 个数
     * @return List<Album>
     */
    public List<Album> createAlbumList(int num) {
        return Album.createAlbums(num);
    }
}
